﻿#pragma execution_character_set("utf-8")

#include "desktopweather.h"
#include "ui_desktopweather.h"

#include <QMessageBox>
#include <QDebug>
#define sysout qDebug()

//https访问配置
void https_ssl_config(QNetworkRequest& NetworkRequest)
{
    QSslConfiguration config = NetworkRequest.sslConfiguration();
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    config.setProtocol(QSsl::TlsV1SslV3);
    NetworkRequest.setSslConfiguration(config);
}

DesktopWeather::DesktopWeather(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::DesktopWeather)
{
    ui->setupUi(this);
    //无边框&置顶
    setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    //Qt::Tool实现任务栏不显示
//    setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool);
//    setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Popup);
    //窗口透明
    setAttribute(Qt::WA_TranslucentBackground);
    //lcdNumber显示位数，默认5，显示时间需改为8
    ui->lcdNumber->setDigitCount(8);
    ui->lcdNumber->setSegmentStyle(QLCDNumber::Flat);
    QPalette lcdpat = ui->lcdNumber->palette();
    /*设置颜色，整体背景颜色 颜色蓝色,此函数的第一个参数可以设置多种。如文本、按钮按钮文字、多种*/
    lcdpat.setColor(QPalette::Normal,QPalette::WindowText,Qt::blue);
    //设置当前窗口的调色板
    ui->lcdNumber->setPalette(lcdpat);
    //托盘实现
    trayicon = new QSystemTrayIcon(this);
    trayicon->setIcon(QIcon(":/common/icons/weather.png"));
    trayicon->setToolTip("桌面天气");
//    trayicon->setContextMenu(menu);//添加头盘菜单
    trayicon->show();

    //初始化
    QTimer::singleShot(100, this, [=]{programInit();});

}

DesktopWeather::~DesktopWeather()
{
    if(NowWeatherTimer->isActive())
        NowWeatherTimer->stop();
    if(Timer->isActive())
        Timer->stop();
    delete ui;
}

void DesktopWeather::programInit()
{
    UserParameter = new QSettings(QApplication::applicationDirPath() + "/user.ini", QSettings::IniFormat, this);
    if(!QFile::exists(QApplication::applicationDirPath() + "/user.ini"))
    {
        QMessageBox MessageBox;
        MessageBox.setWindowIcon(QIcon(":/common/icons/warning.png"));
        MessageBox.setIcon(QMessageBox::Warning);
        MessageBox.setWindowTitle("错误提示窗口");
        MessageBox.setText("\n文件user.ini不存在，已为您重新创建，请写入用户参数后重新打开本程序！\n");
        MessageBox.setWindowFlag(Qt::WindowStaysOnTopHint);
        MessageBox.exec();

        UserParameter->beginGroup("UserParameter");
        UserParameter->setValue("location","");
        UserParameter->setValue("apikey","");
        UserParameter->endGroup();
        close();
    }
    else
    {
        UserParameter->beginGroup("UserParameter");
        user_location = UserParameter->value("location").toString();
        user_apikey = UserParameter->value("apikey").toString();
        UserParameter->endGroup();
        if(user_location.isEmpty() || user_apikey.isEmpty())
        {
            QMessageBox MessageBox;
            MessageBox.setWindowIcon(QIcon(":/common/icons/warning.png"));
            MessageBox.setIcon(QMessageBox::Warning);
            MessageBox.setWindowTitle("错误提示窗口");
            MessageBox.setText("\n用户参数为空，请在文件user.ini中填写用户参数后重新打开本程序！\n");
            MessageBox.setWindowFlag(Qt::WindowStaysOnTopHint);
            MessageBox.exec();
            close();
        }
        else
        {
            NowWeatherUrl += NowWeatherBaseUrl + "location=" + user_location;
            NowWeatherUrl += "&";
            NowWeatherUrl += "key=" + user_apikey;

            LivingIndexUrl = LivingIndexBaseUrl + "location=" + user_location;
            LivingIndexUrl += "&";
            LivingIndexUrl += "key=" + user_apikey;

            ThreeDaysUrl = ThreeDaysBaseUrl + "location=" + user_location;
            ThreeDaysUrl += "&";
            ThreeDaysUrl += "key=" + user_apikey;
        }
    }

    Timer = new QTimer(this);
    connect(Timer, &QTimer::timeout, this, [=]{
        ui->now_date->setText(QDateTime::currentDateTime().toString("yyyy年MM月dd日"));
        ui->weekday->setText(QDateTime::currentDateTime().toString("dddd"));
        ui->lcdNumber->display(QDateTime::currentDateTime().toString("hh:mm:ss"));
    });
    Timer->start(1000);

    NetworkAccessManager = new QNetworkAccessManager(this);
    https_ssl_config(NetworkRequest);

    NowWeatherTimer = new QTimer(this);
    connect(NowWeatherTimer, &QTimer::timeout, this, &DesktopWeather::getNowWeather);
    NowWeatherTimer->start(10*60*1000);
    getNowWeather();

}

void DesktopWeather::keyPressEvent(QKeyEvent* e)
{
    switch (e->key())
    {
    case Qt::Key_F1:    //切换城市
    {
        bool ok;
        QString text = QInputDialog::getText(0,
                                             tr("文本输入对话框"),
                                             tr("请输入城市拼音，如beijing"),
                                             QLineEdit::Normal,
                                             user_location,
                                             &ok,
                                             Qt::WindowStaysOnTopHint
                                             );
        if (ok && !text.isEmpty())
        {
            user_location = text;
            sysout<<user_location;
            //更新ini配置
            UserParameter->beginGroup("UserParameter");
            UserParameter->setValue("location", user_location);
            UserParameter->endGroup();
            //更新URL
            NowWeatherUrl.clear();
            NowWeatherUrl += NowWeatherBaseUrl + "location=" + user_location;
            NowWeatherUrl += "&";
            NowWeatherUrl += "key=" + user_apikey;

            LivingIndexUrl.clear();
            LivingIndexUrl = LivingIndexBaseUrl + "location=" + user_location;
            LivingIndexUrl += "&";
            LivingIndexUrl += "key=" + user_apikey;

            ThreeDaysUrl.clear();
            ThreeDaysUrl = ThreeDaysBaseUrl + "location=" + user_location;
            ThreeDaysUrl += "&";
            ThreeDaysUrl += "key=" + user_apikey;
            //更新天气实况
            getNowWeather();
        }
        break;
    }
    case Qt::Key_F5:    //刷新天气实况
    {
        getNowWeather();
        break;
    }
    case Qt::Key_Escape:
    {
        QMessageBox MessageBox;
        MessageBox.addButton(QMessageBox::Yes);
        MessageBox.addButton(QMessageBox::No);
        MessageBox.setWindowTitle("操作确认窗口");
        MessageBox.setText("\n确定关闭桌面天气吗？\n");
        MessageBox.setWindowFlag(Qt::WindowStaysOnTopHint);
        MessageBox.exec();
        if(MessageBox.result() == QMessageBox::Yes)
            close();
        break;
    }
    }
}

void DesktopWeather::mousePressEvent(QMouseEvent *mousePress)
{
    //mousePress->pos()为鼠标在当前窗口坐标系的坐标，在窗口坐标系中，窗口左上角坐标为(0,0)
    pressPoint = mousePress->pos();
    pressMouseButton = mousePress->button();
    if(pressMouseButton == Qt::RightButton)
    {
        //右键菜单
    }
}

void DesktopWeather::mouseMoveEvent(QMouseEvent *mouseMove)
{
    //左键按下时可拖动
    if(pressMouseButton == Qt::LeftButton)
    {
        /* 移动窗口时以左上角为基点。减去偏移量（鼠标在窗口坐标系中的坐标），使得鼠标移动时保持窗口和鼠标的相对位置不变 */
        move(mouseMove->globalPos() - pressPoint);
    }
}

void DesktopWeather::mouseReleaseEvent(QMouseEvent *mouseRelease)
{
    pressMouseButton = Qt::NoButton;
}

//天气实况
void DesktopWeather::getNowWeather()
{
    NetworkRequest.setUrl(QUrl(NowWeatherUrl));
    connect(NetworkAccessManager, &QNetworkAccessManager::finished, this, &DesktopWeather::NowWeatherReply);
    NetworkAccessManager->get(NetworkRequest);
}
void DesktopWeather::NowWeatherReply(QNetworkReply *Reply)
{
    disconnect(NetworkAccessManager, &QNetworkAccessManager::finished, this, &DesktopWeather::NowWeatherReply);
    if(Reply->error() != QNetworkReply::NoError)
    {
        QMessageBox::warning(0, "错误提示窗口", Reply->errorString());
        return;
    }
    QJsonParseError ParseError;
    QJsonDocument Document = QJsonDocument::fromJson(Reply->readAll(), &ParseError);
    if(ParseError.error != QJsonParseError::NoError)
    {
        sysout<<ParseError.errorString();
        return;
    }
    sysout<<Document;
    QJsonArray results = Document.object().value("results").toArray();

    QJsonObject location = results.at(0).toObject().take("location").toObject();
    QStringList paths = location.value("path").toString().split(",");   //"市,市,省,中国"
    paths.removeFirst();
    QString path = paths.join(","); //"市,省,中国"

    QJsonObject now = results.at(0).toObject().take("now").toObject();
    QString text = now.value("text").toString();
    code = now.value("code").toString().toInt();
    QString temperature = now.take("temperature").toString();

    setNowWeather(path, text, code, temperature);
    getLivingIndex();
}
void DesktopWeather::setNowWeather(const QString& path, const QString& text, int code, const QString& temperature)
{
    ui->location_path->setText(path);
    ui->weather_text->setText(text);
    ui->weather_image->setPixmap(QPixmap(QString(":/weather/icons/black/%1@2x.png").arg(code)));
    ui->air_temperature->setText("气温 " + temperature + " ℃");
}
//生活指数
void DesktopWeather::getLivingIndex()
{
    NetworkRequest.setUrl(QUrl(LivingIndexUrl));
    connect(NetworkAccessManager, &QNetworkAccessManager::finished, this, &DesktopWeather::LivingIndexReply);
    NetworkAccessManager->get(NetworkRequest);
}
void DesktopWeather::LivingIndexReply(QNetworkReply *Reply)
{
    disconnect(NetworkAccessManager, &QNetworkAccessManager::finished, this, &DesktopWeather::LivingIndexReply);
    if(Reply->error() != QNetworkReply::NoError)
    {
        QMessageBox::warning(0, "错误提示窗口", Reply->errorString());
        return;
    }
    QJsonParseError ParseError;
    QJsonDocument Document = QJsonDocument::fromJson(Reply->readAll(), &ParseError);
    sysout<<Document;
    if(ParseError.error != QJsonParseError::NoError)
    {
        sysout<<ParseError.errorString();
        return;
    }
    QJsonArray results = Document.object().value("results").toArray();

    QJsonObject suggestion = results.at(0).toObject().take("suggestion").toObject();

    QString uv = suggestion.take("uv").toObject().take("brief").toString();
    QString dressing = suggestion.take("dressing").toObject().take("brief").toString();
    QString flu = suggestion.take("flu").toObject().take("brief").toString();
    QString car_washing = suggestion.take("car_washing").toObject().take("brief").toString();
    QString travel = suggestion.take("travel").toObject().take("brief").toString();
    QString sport = suggestion.take("sport").toObject().take("brief").toString();

    setLivingIndex(uv, dressing, flu, car_washing, travel, sport);
    getThreeDays();
}
void DesktopWeather::setLivingIndex(const QString& uv,
                                    const QString& dressing,
                                    const QString& flu,
                                    const QString& car_washing,
                                    const QString& travel,
                                    const QString& sport
                                    )
{
    ui->label_uv->setText("紫外线强度：" + uv);
    ui->label_dressing->setText("穿衣参考：" + dressing);
    ui->label_flu->setText("感冒：" + flu);
    ui->label_car_washing->setText("洗车：" + car_washing);
    ui->label_travel->setText("旅游：" + travel);
    ui->label_sport->setText("运动：" + sport);
}
//未来三天天气
void DesktopWeather::getThreeDays()
{
    NetworkRequest.setUrl(QUrl(ThreeDaysUrl));
    connect(NetworkAccessManager, &QNetworkAccessManager::finished, this, &DesktopWeather::ThreeDaysReply);
    NetworkAccessManager->get(NetworkRequest);
}
void DesktopWeather::ThreeDaysReply(QNetworkReply *Reply)
{
    disconnect(NetworkAccessManager, &QNetworkAccessManager::finished, this, &DesktopWeather::ThreeDaysReply);
    if(Reply->error() != QNetworkReply::NoError)
    {
        QMessageBox::warning(0, "错误提示窗口", Reply->errorString());
        return;
    }
    QJsonParseError ParseError;
    QJsonDocument Document = QJsonDocument::fromJson(Reply->readAll(), &ParseError);
    sysout<<Document;
    if(ParseError.error != QJsonParseError::NoError)
    {
        sysout<<ParseError.errorString();
        return;
    }
    QJsonArray daily = Document.object().take("results").toArray().at(0).toObject().take("daily").toArray();

    for(int index = 0; index < daily.size(); index++)
    {
        QJsonObject cur_obj = daily.at(index).toObject();
        QString date = cur_obj.take("date").toString();
        int code_day = cur_obj.take("code_day").toString().toInt();
        QString temp = cur_obj.take("low").toString() + " ~ " + cur_obj.take("high").toString() + " ℃";
        QString text_day = cur_obj.take("text_day").toString();
        QString text_night = cur_obj.take("text_night").toString();
        QString weather = "";
        if(text_day == text_night)
        {
            weather = text_day;
        }
        else
        {
            weather = text_day + " 转 " + text_night;
        }

        setThreeDays(date, code_day, temp, weather, index);
    }
}
void DesktopWeather::setThreeDays(const QString& date,
                                  int code_day,
                                  const QString& temp,
                                  const QString& weather,
                                  int index)
{
    switch(index)
    {
    case 0:
    {
        ui->label_day1->setText(date);
        ui->label_day1png->setPixmap(QPixmap(QString(":/weather/icons/black/%1@1x.png").arg(code)));
        ui->label_day1temp->setText(temp);
        ui->label_day1weather->setText(weather);
        break;
    }
    case 1:
    {
        ui->label_day2->setText(date);
        ui->label_day2png->setPixmap(QPixmap(QString(":/weather/icons/black/%1@1x.png").arg(code_day)));
        ui->label_day2temp->setText(temp);
        ui->label_day2weather->setText(weather);
        break;
    }
    case 2:
    {
        ui->label_day3->setText(date);
        ui->label_day3png->setPixmap(QPixmap(QString(":/weather/icons/black/%1@1x.png").arg(code_day)));
        ui->label_day3temp->setText(temp);
        ui->label_day3weather->setText(weather);
        break;
    }
    }
}
